package com.ld.security.common.shiro;


import com.ld.security.common.shiro.config.ShiroProperties;
import com.ld.security.common.shiro.realm.PassowrdMatcher;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.cache.MemoryConstrainedCacheManager;
import org.apache.shiro.mgt.RememberMeManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.mgt.SubjectFactory;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.session.SessionListener;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;
import org.apache.shiro.session.mgt.eis.SessionDAO;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.mgt.DefaultWebSubjectFactory;
import org.apache.shiro.web.servlet.Cookie;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;

import java.util.Arrays;
import java.util.List;

/**
 * 抽象
 */

public abstract class AbstractShiroConfiguration {



    /**
     * 密码匹配器
     * @return
     */

    public PassowrdMatcher passowrdCredentialsMatcher() {
        PassowrdMatcher passowrdCredentialsMatcher = new PassowrdMatcher();
        return passowrdCredentialsMatcher;
    }


    /**
     * 认证源
     * @return
     */

    public List<Realm> realms() {
        return Arrays.asList();
    }

    /**
     * session 源头
     * @return
     */

    public SessionDAO getSessionDAO() {
            return new EnterpriseCacheSessionDAO();
    }

    /**
     * 配置
     * @return
     */

    public ShiroProperties shiroProperties() {
        return new ShiroProperties();
    }



    /**
     * 代理工厂
     * @return
     */

    public ShiroFilterFactoryBean shiroFilterFactoryBean() {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager());
//        List<StatelessFilter>  filters =   getFilters();
//
//        Map<String,Filter> map = new HashMap<>();
//        for (StatelessFilter filter : filters) {
//            map.put(filter.getFilterName(),filter);
//        }
//
//        shiroFilterFactoryBean.setFilters(map);
//
//        ShiroProperties shiroProperties = shiroProperties();
//        Map<String,String> filterMap = new HashMap();
//
//
//
//        shiroProperties.getFilter().getFilterUrl().forEach((x,y) -> {
//            filterMap.put(y,x);
//        });
//
//
//        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);

        return shiroFilterFactoryBean;
    }

    public SubjectFactory subjectFactory()  {
        return new DefaultWebSubjectFactory();
    }


    /**
     * 安全管理器
     * @return
     */

    public SecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();

        securityManager.setRememberMeManager(rememberMeManager());//记住Cookie
        securityManager.setSubjectFactory(subjectFactory());
        securityManager.setRealms(realms());
        securityManager.setCacheManager(cacheManager());
        securityManager.setSessionManager(sessionManager());
        SecurityUtils.setSecurityManager(securityManager);
        return securityManager;
    }

    /**
     * session 回话监听器
     * @return
     */

    public List<SessionListener> getSessionListeners() {
        List<SessionListener> listeners = Arrays.asList();

        return listeners;
    }

    /**
     * session 管理器
     * @return
     */

    public SessionManager sessionManager() {
        DefaultWebSessionManager  sessionManager = new DefaultWebSessionManager();
        //redisTemplate默认采用的其实是valueSerializer，就算是采用其他ops也一样，这是一个坑。
        //这个name的作用也不大，只是有特色的cookie的名称。
        sessionManager.setDeleteInvalidSessions(true);
        sessionManager.setSessionDAO(getSessionDAO());
        sessionManager.setSessionListeners(getSessionListeners());

        sessionManager.setSessionIdCookieEnabled(true);
        SimpleCookie cookie = new SimpleCookie();
        cookie.setName("session_id");
        sessionManager.setSessionIdCookie(cookie);
        sessionManager.setSessionIdCookieEnabled(true);
        return sessionManager;
    }


    /**
     * 记住我cookie
     * @return
     */

    public RememberMeManager rememberMeManager() {
        Cookie cookie = new SimpleCookie("rememberMe");
       // cookie.setHttpOnly(true);//通过js脚本将无法读取到cookie信息
        cookie.setMaxAge(60 * 60 * 24);//cookie保存一天
        CookieRememberMeManager manager=new CookieRememberMeManager();
        manager.setCookie(cookie);
        return manager;
    }

    /**
     * 缓存管理器
     * @return
     */

    public CacheManager cacheManager() {
        //使用内存缓存
        MemoryConstrainedCacheManager cacheManager=new MemoryConstrainedCacheManager();
        return cacheManager;
    }


    /**
     * 启用shiro注解
     *加入注解的使用，不加入这个注解不生效
     */

    public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor(org.apache.shiro.mgt.SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(securityManager);
        return advisor;
    }



}
